In modern computers, an operating system kernel is responsible for making data available to a central processing unit (“CPU”). In this regard, when a program is scheduled for execution, the kernel causes data that implements the program to be loaded from a mass storage device (e.g., hard drive) into memory that is readily accessible to the CPU. To abstract the complexities of reading and writing data from memory, the operating system implements a virtual memory address space. Using the virtual memory address space, data that implements program functionality may be referenced and retrieved in a standardized way regardless of which input/output (“I/O”) device stores the data.
The memory management functionality implemented by the operating system has been a contributing factor in making a computer vulnerable to malware. For example, data that implements program functionality may be loaded into common locations (e.g., memory addresses) on computers that execute the same versions of an operating system or other programs. In an exploit commonly known as a buffer overflow, a malware author identifies an existing operation that copies data to a buffer in memory. In this type of exploit, a limited segment of memory is allocated to the buffer and a check to determine whether the allocated area of memory is sufficient to complete an operation was not performed. As a result, the malware causes excess information to overwrite data at a known location in memory that, for example, may be used to store a privileged software component. In this way, the malware is able to redirect program execution to program code associated with the malware without triggering a scan by anti-virus software. When a computer malware gains control of a computer using this type of attack, the potential damage to the computer is substantial as the process corrupted by the malware may be highly trusted, running with system and/or administrator privileges. As a result, the malware will inherit the same trust level as the process that was corrupted.
To prevent the address space that stores a software component from being identified, various techniques have been proposed. In one technique, software components are randomly assigned a memory address space so that different locations in memory are used each time the software component is executed. As a result, malware authors may be unable to identify the memory location allocated to the software component that the malware is designed to exploit. However, the memory address space available to programs is a finite resource. A mere random assignment of address spaces results in memory being fragmented. As a result, implementing memory management schemas that are designed to prevent malware authors from being able to identify the memory address space allocated to particular software components have had a negative impact on system performance.